home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 25 / AACD 25.iso / AACD / Magazine / Online / QMail / source / maildir2mbox.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-15  |  4.4 KB  |  163 lines

  1. #include "readwrite.h"
  2. #include "prioq.h"
  3. #include "env.h"
  4. #include "stralloc.h"
  5. #include "subfd.h"
  6. #include "substdio.h"
  7. #include "getln.h"
  8. #include "error.h"
  9. #include "open.h"
  10. #include "lock.h"
  11. #include "gfrom.h"
  12. #include "str.h"
  13. #include "exit.h"
  14. #include "myctime.h"
  15. #include "maildir.h"
  16.  
  17. char *mbox;
  18. char *mboxtmp;
  19.  
  20. stralloc filenames = {0};
  21. prioq pq = {0};
  22. prioq pq2 = {0};
  23.  
  24. stralloc line = {0};
  25.  
  26. stralloc ufline = {0};
  27.  
  28. char inbuf[SUBSTDIO_INSIZE];
  29. char outbuf[SUBSTDIO_OUTSIZE];
  30.  
  31. #define FATAL "maildir2mbox: fatal: "
  32. #define WARNING "maildir2mbox: warning: "
  33.  
  34. void die_nomem() { strerr_die2x(111,FATAL,"out of memory"); }
  35.  
  36. void main()
  37. {
  38.  substdio ssin;
  39.  substdio ssout;
  40.  struct prioq_elt pe;
  41.  int fdoldmbox;
  42.  int fdnewmbox;
  43.  int fd;
  44.  int match;
  45.  int fdlock;
  46.  
  47.  umask(077);
  48.  
  49.  mbox = env_get("MAIL");
  50.  if (!mbox) strerr_die2x(111,FATAL,"MAIL not set");
  51.  mboxtmp = env_get("MAILTMP");
  52.  if (!mboxtmp) strerr_die2x(111,FATAL,"MAILTMP not set");
  53.  
  54.  if (maildir_chdir() == -1)
  55.    strerr_die1(111,FATAL,&maildir_chdir_err);
  56.  maildir_clean(&filenames);
  57.  if (maildir_scan(&pq,&filenames,1,1) == -1)
  58.    strerr_die1(111,FATAL,&maildir_scan_err);
  59.  
  60.  if (!prioq_min(&pq,&pe)) _exit(0); /* nothing new */
  61.  
  62.  fdlock = open_append(mbox);
  63.  if (fdlock == -1)
  64.    strerr_die4sys(111,FATAL,"unable to lock ",mbox,": ");
  65.  if (lock_ex(fdlock) == -1)
  66.    strerr_die4sys(111,FATAL,"unable to lock ",mbox,": ");
  67.  
  68.  fdoldmbox = open_read(mbox);
  69.  if (fdoldmbox == -1)
  70.    strerr_die4sys(111,FATAL,"unable to read ",mbox,": ");
  71.  
  72.  fdnewmbox = open_trunc(mboxtmp);
  73.  if (fdnewmbox == -1)
  74.    strerr_die4sys(111,FATAL,"unable to create ",mboxtmp,": ");
  75.  
  76.  substdio_fdbuf(&ssin,read,fdoldmbox,inbuf,sizeof(inbuf));
  77.  substdio_fdbuf(&ssout,write,fdnewmbox,outbuf,sizeof(outbuf));
  78.  
  79.  switch(substdio_copy(&ssout,&ssin))
  80.   {
  81.    case -2: strerr_die4sys(111,FATAL,"unable to read ",mbox,": ");
  82.    case -3: strerr_die4sys(111,FATAL,"unable to write to ",mboxtmp,": ");
  83.   }
  84.  
  85.  while (prioq_min(&pq,&pe))
  86.   {
  87.    prioq_delmin(&pq);
  88.    if (!prioq_insert(&pq2,&pe)) die_nomem();
  89.  
  90.    fd = open_read(filenames.s + pe.id);
  91.    if (fd == -1)
  92.      strerr_die4sys(111,FATAL,"unable to read $MAILDIR/",filenames.s + pe.id,": ");
  93.    substdio_fdbuf(&ssin,read,fd,inbuf,sizeof(inbuf));
  94.  
  95.    if (getln(&ssin,&line,&match,'\n') != 0)
  96.      strerr_die4sys(111,FATAL,"unable to read $MAILDIR/",filenames.s + pe.id,": ");
  97.    
  98.    if (!stralloc_copys(&ufline,"From XXX ")) die_nomem();
  99.    if (match)
  100.      if (stralloc_starts(&line,"Return-Path: <"))
  101.       {
  102.        if (line.s[14] == '>')
  103.     {
  104.          if (!stralloc_copys(&ufline,"From MAILER-DAEMON ")) die_nomem();
  105.     }
  106.        else
  107.     {
  108.      int i;
  109.          if (!stralloc_ready(&ufline,line.len)) die_nomem();
  110.          if (!stralloc_copys(&ufline,"From ")) die_nomem();
  111.      for (i = 14;i < line.len - 2;++i)
  112.        if ((line.s[i] == ' ') || (line.s[i] == '\t'))
  113.          ufline.s[ufline.len++] = '-';
  114.        else
  115.          ufline.s[ufline.len++] = line.s[i];
  116.          if (!stralloc_cats(&ufline," ")) die_nomem();
  117.     }
  118.       }
  119.    if (!stralloc_cats(&ufline,myctime(pe.dt))) die_nomem();
  120.    if (substdio_put(&ssout,ufline.s,ufline.len) == -1)
  121.      strerr_die4sys(111,FATAL,"unable to write to ",mboxtmp,": ");
  122.  
  123.    while (match && line.len)
  124.     {
  125.      if (gfrom(line.s,line.len))
  126.        if (substdio_puts(&ssout,">") == -1)
  127.          strerr_die4sys(111,FATAL,"unable to write to ",mboxtmp,": ");
  128.      if (substdio_put(&ssout,line.s,line.len) == -1)
  129.        strerr_die4sys(111,FATAL,"unable to write to ",mboxtmp,": ");
  130.      if (!match)
  131.       {
  132.        if (substdio_puts(&ssout,"\n") == -1)
  133.          strerr_die4sys(111,FATAL,"unable to write to ",mboxtmp,": ");
  134.        break;
  135.       }
  136.      if (getln(&ssin,&line,&match,'\n') != 0)
  137.        strerr_die4sys(111,FATAL,"unable to read $MAILDIR/",filenames.s + pe.id,": ");
  138.     }
  139.    if (substdio_puts(&ssout,"\n"))
  140.      strerr_die4sys(111,FATAL,"unable to write to ",mboxtmp,": ");
  141.  
  142.    close(fd);
  143.   }
  144.  
  145.  if (substdio_flush(&ssout) == -1)
  146.    strerr_die4sys(111,FATAL,"unable to write to ",mboxtmp,": ");
  147.  if (fsync(fdnewmbox) == -1)
  148.    strerr_die4sys(111,FATAL,"unable to write to ",mboxtmp,": ");
  149.  if (close(fdnewmbox) == -1) /* NFS dorks */
  150.    strerr_die4sys(111,FATAL,"unable to write to ",mboxtmp,": ");
  151.  if (rename(mboxtmp,mbox) == -1)
  152.    strerr_die6(111,FATAL,"unable to move ",mboxtmp," to ",mbox,": ",&strerr_sys);
  153.  
  154.  while (prioq_min(&pq2,&pe))
  155.   {
  156.    prioq_delmin(&pq2);
  157.    if (unlink(filenames.s + pe.id) == -1)
  158.      strerr_warn4(WARNING,"$MAILDIR/",filenames.s + pe.id," will be delivered twice; unable to unlink: ",&strerr_sys);
  159.   }
  160.  
  161.  _exit(0);
  162. }
  163.